package cn.xshi.file.util;
import cn.hutool.core.collection.CollectionUtil;
import cn.xshi.file.config.MinioConfig;
import cn.xshi.file.model.Attachment;
import cn.xshi.file.service.AttachmentService;
import cn.xshi.file.util.office.OfficeUtil;
import cn.xshi.common.base.BaseService;
import cn.xshi.common.base.BaseUtils;
import cn.xshi.common.constant.PathConstant;
import cn.xshi.common.entity.AttachmentEntity;
import cn.xshi.common.entity.PathEntity;
import cn.xshi.common.entity.UploadEntity;
import cn.xshi.common.util.AllUtils;
import cn.xshi.common.util.ExceptionUtil;
import cn.xshi.common.util.StringUtil;
import cn.xshi.common.util.file.FileUtil;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import javax.annotation.Resource;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
 * @Desc 附件管理
 * @Author 邓纯杰
 * @CreateTime 2012-12-12 12:12:12
 */
@Service
public class FileService extends BaseService{

    @Resource
    MinIOUtil minIOUtil;

    @Resource
    MinioConfig minioConfig;

    @Resource
    OfficeUtil officeUtil;

    @Resource
    private AttachmentService attachmentService;

    @Resource
    public BaseUtils baseUtils;

    /**
     * 通用文件上传
     * @param uploadEntity
     * @param path 上传的路径
     * @return
     * @throws IllegalStateException
     * @throws IOException
     */
    public List<Attachment> upLoad(UploadEntity uploadEntity, List<MultipartFile> multipartFileList, String path) throws IllegalStateException, IOException{
        List<Attachment> list = new ArrayList<Attachment>();
        File filePath = new File(path);
        if(!filePath.exists()){
            filePath.mkdirs();
        }
        String relativePath = StringUtil.isEmpty(uploadEntity.getPathRelativek())?"":uploadEntity.getPathRelativek();
        String validateparameter = uploadEntity.getValidateparameter();
        String validateSize = uploadEntity.getValidateSize();
        String pathAbsolutek = uploadEntity.getPathAbsolutek();
        String pathRelativek =uploadEntity.getPathRelativek();
        String pathUrlk = uploadEntity.getPathUrlk();

        //先判断request中是否包涵multipart类型的数据，
        if (!CollectionUtil.isEmpty(multipartFileList)) {
            for(MultipartFile file : multipartFileList){
                if(file != null){
                    //验证图片类型 验证图片大小
                    if(validate(file,validateparameter,validateSize)){
                        String fileName = file.getOriginalFilename();
                        int lastD = fileName.lastIndexOf('.');
                        String newName = AllUtils.getRandom()+fileName.substring(lastD,fileName.length());

                        /*
                        方案一.采用MinIO模式上传
                        try {
                            minIOUtil.putObject(minioConfig.getBucketName(),newName,file.getInputStream(),file.getContentType());
                        }catch (Exception e){
                            throw new ExceptionUtil("上传文件至MinIO服务异常",e.getCause());
                        }*/

                        /*
                        方案二.采用文件拷贝模式上传
                        写文件到本地*/
                        //File localFile = new File(path);
                        //file.transferTo(localFile);
                        FileUtils.copyInputStreamToFile(file.getInputStream(), new File(path,newName));//采用文件拷贝模式上传

                        /* 方案三.FTP模式
//						FtpUtil.uploadFile(path, newName, file.getInputStream());//此处可以修改成Ftp操作如下:
                        */
                        Attachment attachment = new Attachment();
                        attachment.setId(toUUID());
                        attachment.setCreateTime(getDate());
                        attachment.setName(newName);
                        attachment.setPath(relativePath+ Constant.slash +newName);
                        attachment.setSize(""+file.getSize());
                        attachment.setType(file.getContentType());
                        attachment.setTitle(fileName);
                        attachment.setCreateId(getCurrentAccountId());
                        attachment.setPathAbsolutek(pathAbsolutek);
                        attachment.setPathRelativek(pathRelativek);
                        attachment.setPathUrlk(pathUrlk);
                        list.add(attachment);
                    }else {

                    }
                }
            }
        }
        syncConvertUpload(uploadEntity,list,multipartFileList);//同步执行文件转换如doc,docx,xls,ppt等文件转成pdf并异步上传至文件服务器
        return list;
    }

    /**
     * 验证文件合法
     * @param file
     * @param validateparameter 格式如:png,jpg,bmp 以逗号分隔
     * @param validateSize 格式如:1024-10240以-分隔
     * @return
     */
    public static boolean validate(MultipartFile file,String validateparameter,String validateSize){
        if(null != validateparameter && !"".equals(validateparameter) && !StringUtils.isEmpty(validateparameter)){
            String[] v = validateparameter.split(",");
            String ftype = FileUtil.getFilePreFix(file.getOriginalFilename()).toLowerCase();
            int flag=0;
            for(int i = 0; i < v.length; i++){
                if(ftype.equals(v[i].toLowerCase())){
                    flag++;
                }
            }
            if(flag==0){
                throw new ExceptionUtil("文件类型不合法：文件只能上传["+validateparameter+"]格式");
            }
        }
        if(null != validateSize && !"".equals(validateSize) && !StringUtils.isEmpty(validateSize)){
            String[] siz = validateSize.split("-");
            long fsize = file.getSize();
            //说明只有一个参数 此时平台默认上传不超过该大小
            if(siz.length==1){
                if(fsize>new Long(siz[0])){
                    throw new ExceptionUtil("文件大小不合法：文件大小不能超过["+siz[0]+"]Kb");
                }
            }else if(siz.length>2 || siz.length < 1){
                throw new ExceptionUtil("文件大小验证规则不符合：请参考格式如:1024-10240以-分隔");
            }else{
                if(fsize < new Long(siz[0])){
                    throw new ExceptionUtil("文件大小不合法：文件大小最小必须超过["+siz[0]+"]Kb");
                }
                if(fsize > new Long(siz[1])){
                    throw new ExceptionUtil("文件大小不合法：文件大小不能超过["+siz[1]+"]Kb");
                }
            }
        }
        return true;
    }

    /**
     * 同步执行文件转换如doc,docx,xls,ppt等文件转成pdf并异步上传至文件服务器
     * @param uploadEntity
     * @param attachmentList
     * @param multipartFileList
     */
    public void syncConvertUpload(UploadEntity uploadEntity, List<Attachment> attachmentList, List<MultipartFile> multipartFileList){
        Thread thread = new Thread(new FileWork(uploadEntity,attachmentList,multipartFileList));
        thread.setDaemon(true);
        thread.start();
    }

    /**
     * 异步线程类
     */
    class FileWork implements Runnable{

        private UploadEntity uploadEntity;

        private List<Attachment> attachmentList;

        private List<MultipartFile> multipartFileList;

        public FileWork(UploadEntity uploadEntity, List<Attachment> attachmentList, List<MultipartFile> multipartFileList) {

            this.uploadEntity = uploadEntity;

            this.attachmentList = attachmentList;

            this.multipartFileList = multipartFileList;
        }
        @Override
        public void run() {
//            officeUtil.doc2PDF();
        }
    }

    /**
     * 按条件获取附件所有相关字段信息 并且与相关附件字段匹配
     * @param attachmentEntity
     * field_name与xt_attachment_id必须满足的规则是如parameter={field_name:'field1,field2,field3',xt_attachment_id:'1,2,3'}一一对应
     */
    public List<Attachment> getBatchAttachmentPathPP(AttachmentEntity attachmentEntity){
        Map<String, Object> condition = new HashMap<String, Object>();
        List<PathEntity> pathEntities = baseUtils.getSysPathCache(PathConstant.SYS_SOURCES_BASE_URL);
        if(null == pathEntities || pathEntities.isEmpty()){
            throw new ExceptionUtil("未能获取到路径");
        }
        PathEntity pathEntity = pathEntities.get(0);
        String path = pathEntity.getPath();
        List<Attachment> attachmentList = new ArrayList<>();
        if(!com.github.pagehelper.util.StringUtil.isEmpty(attachmentEntity.getId())){
            condition.put("id", attachmentEntity.getId().split(","));
            attachmentList = attachmentService.getAttachmentList(condition);
            for(Attachment attachment :attachmentList){
                //判断该附件是否使用自定义path_urlk
                if(!StringUtils.isEmpty(attachment.getPathUrlk())){
                    path = baseUtils.getSysPathCache(attachment.getPathUrlk()).get(0).getPath();
                }
                //相对路径
                String relative_path = baseUtils.getSysPathCache(PathConstant.SYS_SOURCES_DEFAULT_RELATIVE_PATH).get(0).getPath();
                //整个路径如http://www.jehc.com/images/img.png
                attachment.setFullUrl( path+ attachment.getPath());
            }
        }
        return attachmentList;
    }

    /**
     * 查询单个
     * @param id
     * @return
     */
    public Attachment getAttachmentPath(String id){
        Attachment attachment = attachmentService.getAttachmentById(id);
        return attachment;
    }
}
